---
title: テンプレート式のリファレンス
i18nReady: true
---

Astroコンポーネントの構文はHTMLのスーパーセットです。この構文はHTMLやJSXを書いたことのある人にとって親しみやすいように設計され、コンポーネントやJavaScriptの式がサポートされています。


## JSXライクな式

Astroコンポーネントのフロントマターのコードフェンス（`---`）の間に、JavaScriptのローカル変数を定義できます。そして、JSXライクな式を使って、変数をコンポーネントのHTMLテンプレートに注入できます。

:::note[動的vsリアクティブ]
この方法により、フロントマターで計算された**動的**な値をテンプレートに含めることができます。しかし、一度含められたこれらの値は**リアクティブ**ではなく、変化することはありません。Astroコンポーネントは、レンダリングの際に一度だけ実行されるテンプレートです。

以下で[AstroとJSXの違い](#astroとjsxの違い)に関する例をいくつか紹介します。
:::

### 変数

ローカル変数は、波括弧の構文を使ってHTMLに追加できます。

```astro title="src/components/Variables.astro" "{name}"
---
const name = "Astro";
---
<div>
  <h1>Hello {name}!</h1>  <!-- <h1>Hello Astro!</h1> を出力 -->
</div>
```

### 動的属性

ローカル変数を波括弧で囲むことで、HTML要素とコンポーネントの両方に属性値を渡せます。

```astro title="src/components/DynamicAttributes.astro" "{name}" "${name}"
---
const name = "Astro";
---
<h1 class={name}>属性を式で指定できます</h1>

<MyComponent templateLiteralNameAttribute={`私の名前は${name}です`} />
```

:::caution
HTML属性は文字列に変換されるため、関数やオブジェクトをHTML要素に渡すことはできません。
たとえば、Astroコンポーネント内のHTML要素にイベントハンドラを割り当てることはできません。

```astro title="dont-do-this.astro"
---
function handleClick () {
    console.log("ボタンがクリックされました！");
}
---
<!-- ❌ これは動作しません！ ❌ -->
<button onClick={handleClick}>クリックしても何も起こりません！</button>
```

代わりに、通常のJavaScriptと同じように、クライアントサイドスクリプトを使用してイベントハンドラを追加します。

```astro title="do-this-instead.astro"
<button id="button">クリックしてください</button>
<script>
  function handleClick () {
    console.log("ボタンがクリックされました！");
  }
  document.getElementById("button").addEventListener("click", handleClick);
</script>
```
:::

### 動的HTML

ローカル変数をJSXのような関数で使用して、動的に生成されるHTML要素を作成できます。

```astro title="src/components/DynamicHtml.astro" "{item}"
---
const items = ["犬", "猫", "カモノハシ"];
---
<ul>
  {items.map((item) => (
    <li>{item}</li>
  ))}
</ul>
```

Astroは、JSXと同様に論理演算子と三項演算子を使用して、HTMLを条件に応じて表示できます。

```astro title="src/components/ConditionalHtml.astro" "visible"
---
const visible = true;
---
{visible && <p>表示！</p>}

{visible ? <p>表示！</p> : <p>あるいはこちらを表示！</p>}
```

### 動的タグ

HTMLタグ名を変数に割り当てるか、コンポーネントのインポートを再割り当てすることで、動的タグも使用できます。

```astro title="src/components/DynamicTags.astro" /Element|(?<!My)Component/
---
import MyComponent from "./MyComponent.astro";
const Element = 'div'
const Component = MyComponent;
---
<Element>Hello!</Element> <!-- <div>Hello!</div> としてレンダリングされます -->
<Component /> <!-- <MyComponent /> としてレンダリングされます -->
```

動的タグを使用する場合は、以下の点に注意してください。

- **変数名は大文字で始める必要があります。** たとえば、`element`ではなく`Element`を使用します。そうしないと、Astroは変数名をそのままHTMLタグとしてレンダリングしようとします。

- **ハイドレーションディレクティブは使えません。**[`client:*`ハイドレーションディレクティブ](/ja/guides/framework-components/#hydrating-interactive-components)を使用する場合、Astroはバンドルする対象のコンポーネントを知る必要がありますが、動的タグパターンではこれが機能しなくなるためです。

- **[define:vars ディレクティブ](/ja/reference/directives-reference/#definevars) はサポートされていません。** もし、子要素を追加の要素(例えば`<div>`)でラップすることができない場合は、 `style={``--myVar:${value}``}` を手動で要素に追加することができます。

### フラグメント

Astroでは `<> </>` 表記を使用でき、組み込みの `<Fragment />` コンポーネントを提供しています。このコンポーネントは、HTML文字列を注入するために [`set:*` ディレクティブ](/ja/reference/directives-reference/#sethtml) を追加する際に、ラッパー要素を避けるのに役立ちます。

次の例では、`<Fragment />` コンポーネントを使用して段落テキストをレンダリングします。

```astro title="src/components/SetHtml.astro" "Fragment"
---
const htmlString = '<p>生のHTMLコンテンツ</p>';
---
<Fragment set:html={htmlString} />
```

### AstroとJSXの違い

Astroコンポーネントの構文はHTMLのスーパーセットです。HTMLやJSXを書いたことのある人にとって親しみやすいように設計されてはいますが、`.astro`ファイルとJSXの間にはいくつかの重要な違いがあります。

#### 属性

Astroでは、JSXで使用されている`camelCase`ではなく、すべてのHTML属性に標準の`kebab-case`形式を使用します。これは、Reactではサポートされていない`class`でも同様です。

```jsx del={1} ins={2} title="example.astro"
<div className="box" dataValue="3" />
<div class="box" data-value="3" />
```

#### 複数の要素

Astroコンポーネントテンプレートは複数の要素をレンダリングできます。その際、JavaScriptやJSXとは異なり、全体を単一の`<div>`や`<>`で囲む必要はありません。

```astro title="src/components/RootElements.astro"
---
// 複数の要素を含むテンプレート
---
<p>全体をコンテナ要素で囲む必要はありません。</p>
<p>Astroではテンプレート内に複数のルート要素を置けます。</p>
```

#### コメント

Astroでは、標準のHTMLコメントまたはJavaScriptスタイルのコメントを使用できます。

```astro title="example.astro"
---
---
<!-- .astroファイルでは、HTMLのコメント構文が使えます -->
{/* JSのコメント構文も有効です */}
```

:::caution
HTMLスタイルのコメントはブラウザのDOMに含まれますが、JSのコメントはスキップされます。TODOメッセージやその他の開発専用の説明を残したい場合は、JavaScriptスタイルのコメントを使用することをお勧めします。
:::


## コンポーネントユーティリティ

### `Astro.slots`

`Astro.slots` には、Astroコンポーネントのスロットの子要素を変更するためのユーティリティ関数が含まれています。

#### `Astro.slots.has()`

<p>

**Type:** `(slotName: string) => boolean`
</p>

`Astro.slots.has()` を使用して、特定のスロット名のコンテンツが存在するかどうかを確認できます。これは、スロットのコンテンツをラップしたいが、スロットが使用されている場合にのみラッパー要素をレンダリングしたい場合に便利です。

```astro  title="src/pages/index.astro"
---
---
<slot />

{Astro.slots.has('more') && (
  <aside>
    <h2>More</h2>
    <slot name="more" />
  </aside>
)}
```

#### `Astro.slots.render()`

<p>

**Type:** `(slotName: string, args?: any[]) => Promise<string>`
</p>

`Astro.slots.render()` を使用して、スロットのコンテンツをHTML文字列として非同期にレンダリングできます。

```astro
---
const html = await Astro.slots.render('default');
---
<Fragment set:html={html} />
```

:::note
これは高度なユースケースです！ほとんどの場合、[`<slot />` 要素](/ja/basics/astro-components/#スロット)を使用してスロットのコンテンツをレンダリングする方が簡単です。
:::

`Astro.slots.render()` は、2番目のオプションの引数として、任意の子関数に転送されるパラメータの配列を受け取ります。これは、カスタムユーティリティコンポーネントに役立ちます。

たとえば、この `<Shout />` コンポーネントは、`message` propを大文字に変換し、デフォルトスロットに渡します。

```astro title="src/components/Shout.astro" "await Astro.slots.render('default', [message])"
---
const message = Astro.props.message.toUpperCase();
let html = '';
if (Astro.slots.has('default')) {
  html = await Astro.slots.render('default', [message]);
}
---
<Fragment set:html={html} />
```

`<Shout />` の子として渡されたコールバック関数は、すべて大文字の `message` パラメータを受け取ります。

```astro title="src/pages/index.astro"
---
import Shout from "../components/Shout.astro";
---
<Shout message="slots!">
  {(message) => <div>{message}</div>}
</Shout>

<!-- <div>SLOTS!</div> としてレンダリングされます -->
```

コールバック関数は、`slot` 属性を持つHTML要素タグでラップすることで、名前付きスロットに渡すことができます。この要素はコールバックを名前付きスロットに転送するためにのみ使用され、ページにはレンダリングされません。

```astro
<Shout message="slots!">
  <fragment slot="message">
    {(message) => <div>{message}</div>}
  </fragment>
</Shout>
```

ラッパータグには、標準のHTML要素またはコンポーネントとして解釈されない小文字のタグ（例：`<Fragment />` の代わりに `<fragment>`）を使用します。HTMLの `<slot>` 要素はAstroのスロットとして解釈されるため、使用しないでください。

### `Astro.self`

`Astro.self` を使用すると、Astroコンポーネントを再帰的に呼び出すことができます。この動作により、コンポーネントテンプレート内で `<Astro.self>` を使用して、Astroコンポーネントを自身の中からレンダリングできます。これは、大規模なデータストアやネストされたデータ構造を反復処理するのに役立ちます。

```astro
---
// NestedList.astro
const { items } = Astro.props;
---
<ul class="nested-list">
  {items.map((item) => (
    <li>
      <!-- ネストされたデータ構造がある場合は、`<Astro.self>` をレンダリングします -->
      <!-- そして、再帰呼び出しでpropを渡すことができます -->
      {Array.isArray(item) ? (
        <Astro.self items={item} />
      ) : (
        item
      )}
    </li>
  ))}
</ul>
```

このコンポーネントは次のように使用できます。

```astro
---
import NestedList from './NestedList.astro';
---
<NestedList items={['A', ['B', 'C'], 'D']} />
```

そして、次のようなHTMLをレンダリングします。

```html
<ul class="nested-list">
  <li>A</li>
  <li>
    <ul class="nested-list">
      <li>B</li>
      <li>C</li>
    </ul>
  </li>
  <li>D</li>
</ul>
